﻿using AutoMapper;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_ProcecureMainBusiness : BaseBusiness<PB_ProcecureMain>, IPB_ProcecureMainBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IMapper _mapper;
        public PB_ProcecureMainBusiness(IDbAccessor db,
            IOperator @operator,
            IMapper mapper/*,
            IPB_ProcecureSubBusiness psub*/
            )
            : base(db)
        {
            _operator = @operator;
            _mapper = mapper;
            //_psub = psub;
        }

        //IPB_ProcecureSubBusiness _psub { get; }

        #region 外部接口

        public async Task<PageResult<PB_ProcecureMain>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_ProcecureMain>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_ProcecureMain, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            //q = q.Where(p => _operator.Property.DeptIds.Contains(p.DeptId));
            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PB_ProcecureMain> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        [DataAddLog(UserLogType.工序管理, "Name", "工序管理")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "工序编号" })]
        public async Task AddDataAsync(PB_ProcecureMain data)
        {
            data.Status = false;
            await InsertAsync(data);
        }

        [DataEditLog(UserLogType.工序管理, "Name", "工序管理")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "工序编号" })]
        public async Task UpdateDataAsync(PB_ProcecureMain data)
        {
            await UpdateAsync(data);
        }

        [DataDeleteLog(UserLogType.工序管理, "Name", "工序管理")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            if (await Db.GetIQueryable<PB_ProcecureSub>().AnyAsync(x => ids.Contains(x.ParentId)))
            {
                throw new BusException("删除失败！该工艺下有工序禁止删除！");
            }
            await DeleteAsync(ids);
        }


        public async Task<PageResult<PB_ProcecureMain>> GetDataListByDepartment(string DeptId)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_ProcecureMain>();

            //筛选
            if (!DeptId.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_ProcecureMain, bool>(
                    ParsingConfig.Default, false, $@"DeptId.Contains(@0)", DeptId);
                where = where.And(newWhere);
            }
            //q = q.Where(w => _operator.Property.DeptIds.Contains(w.DeptId));
            return await q.Where(where).GetPageResultAsync(new PageInput());
        }

        /// <summary>
        /// 工艺Dto
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public  async Task<PageResult<PB_ProcecureMainDto>> GetDataListAsyncs(PageInput<ConditionDTO> input)
        {
            var search = input.Search;
            Expression<Func<PB_ProcecureMain, Base_Department,  PB_ProcecureMainDto >> select = (a, b) => new PB_ProcecureMainDto
            {
                DepartmentName = b.Name,
              
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DeptId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                  
                    select @select.Invoke(a, b);

            if (!search.Keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.Keyword}%";
                q = q.Where(x =>
                      EF.Functions.Like(x.Name, keyword)
                      || EF.Functions.Like(x.Code, keyword));
            }
            q = q.Where(m=>_operator.Property.DeptIds.Contains(m.DeptId));
            return await q.GetPageResultAsync(new PageInput());
        }

        [DataAddLog(UserLogType.工序管理, "Name", "工序管理")]
        [Transactional]
        public async Task AddData(PB_ProcecureMainListDTO data)
        {
            PB_ProcecureMain pm = new PB_ProcecureMain
            {
                Id = data.Id,
                Code = data.Code,
                Name = data.Name,
                DeptId = data.DeptId,
                Remarks = data.Remarks,
                Version = 1,
                CreateTime = data.CreateTime,
                CreatorId = data.CreatorId,
                Deleted = data.Deleted,
                Status = data.Status,
                VerState = true,
                ImgSrc = data.ImgSrc,
                ImgCode = data.ImgCode
            };
            await InsertAsync(pm);
            var userRoleList = data.subData.Select(x => new PB_ProcecureSub
            {
                Id = IdHelper.GetId(),
                Code = x.Code,
                Name = x.Name,
                Sketch = x.Sketch,
                IsPoint = x.IsPoint,
                IsBackflush = x.IsBackflush,
                IsOutsourcing = x.IsOutsourcing,
                SupplierId = x.SupplierId,
                IsOption = x.IsOption,
                OutsidePlan = x.OutsidePlan,
                Isapplication = x.Isapplication,
                Days = x.Days,
                Ratio = x.Ratio,
                Remarks = x.Remarks,
                CreateTime = data.CreateTime,
                CreatorId = data.CreatorId,
                Deleted = data.Deleted,
                ParentId = data.Id
            }).ToList();
            await Db.InsertAsync(userRoleList);
        }

        [DataAddLog(UserLogType.工序管理, "Name", "工序管理")]
        [Transactional]
        public async Task UpdateData(PB_ProcecureMainListDTO data)
        {
            //修改Id的数据为旧版本
            await ExecuteSqlAsync("update PB_ProcecureMain set VerState=0 where Id='" + data.Id + "'");
            //新增当前数据为新版本版本号加1
            PB_ProcecureMain pm = new PB_ProcecureMain
            {
                Id = IdHelper.GetId(),
                Code = data.Code,
                Name = data.Name,
                DeptId = data.DeptId,
                Remarks = data.Remarks,
                Version = (data.Version + 1),
                CreateTime = DateTime.Now,
                CreatorId = data.CreatorId,
                Deleted = data.Deleted,
                Status = data.Status,
                VerState = true,
                ImgSrc = data.ImgSrc,
                ImgCode = data.ImgCode
            };
            await Db.InsertAsync(pm);
            //添加新的子工序信息
            var userRoleList = data.subData.Select(x => new PB_ProcecureSub
            {
                Id = IdHelper.GetId(),
                Code = x.Code,
                Name = x.Name,
                Sketch = x.Sketch,
                IsPoint = x.IsPoint,
                IsBackflush = x.IsBackflush,
                IsOutsourcing = x.IsOutsourcing,
                SupplierId = x.SupplierId,
                IsOption = x.IsOption,
                OutsidePlan = x.OutsidePlan,
                Isapplication = x.Isapplication,
                Days = x.Days,
                Ratio = x.Ratio,
                Remarks = x.Remarks,
                CreateTime = x.CreateTime,
                CreatorId = x.CreatorId,
                Deleted = x.Deleted,
                ParentId = pm.Id
            }).ToList();
            await Db.InsertAsync(userRoleList);
        }

        //public async Task<string> GetDataDetails(string Id)
        //{
        //    var q = GetIQueryable().Where(x => x.Id == Id);
        //    var qitem = await _psub.GetDatalist(Id);
        //    var data = new
        //    {
        //        Pdata = q,
        //        PdataItem = qitem
        //    };
        //    string Json = data.ToJson();
        //    return Json;
        //}
        public IQueryable<T> GetQueryable<T>() where T : class, new()
        {
            return Db.GetIQueryable<T>();
        }
        #region 通过工序id返回子工序list集合
        public async Task<PB_ProcecureMainList> GetDataProceureMain(string ParentId)
        {
            PB_ProcecureMainList pblist = new PB_ProcecureMainList();
            pblist.PB_ProcecureMain = GetQueryable<PB_ProcecureMain>().Where(x => x.Id == ParentId).FirstOrDefault();
            //pblist.PB_ProcecureSub = await _psub.GetDatalist(ParentId);
            var q = Db.GetIQueryable<PB_ProcecureSub>();
            pblist.PB_ProcecureSub = await q.Where(s => s.ParentId.Equals(ParentId)).ToListAsync();
            return pblist;
        }
        #endregion


        #endregion

        #region 私有成员

        #endregion
    }
}